
`timescale 1ns / 1ps

module tb_cpu(

);

reg clk;
reg rst;

wire [31:0] i_data;
wire [31:0] o_data;
wire [31:0] o_addr;
wire 				o_we;

cpu cpu_DUT(
	.clk(clk),
	.rst(rst),
	.i_data(i_data),
	.o_we(o_we),
	.o_addr(o_addr),
	.o_data(o_data)
);


sys_mem sys_mem_DUT(
	.i_addr(o_addr[7:0]),
	.i_we(o_we),
	.i_data(o_data),
	.o_data(i_data)
);

initial
begin
	clk = 0;
	rst = 0;

	init_micro_mem;
	init_sys_mem;
	init_regs;
	init_map_rom;
	
	reset_system;
	
	#10
	run_cycles(40);
	#10
	$finish;
end

always
	#5 clk = ~clk;
	
task init_micro_mem;
begin
	$readmemb("micro_mem79.mem", cpu_DUT.micro_mem_inst.mem );	
end
endtask

task init_sys_mem;
begin
	$readmemb("sys_mem32.mem", sys_mem_DUT.mem );	
end
endtask

task init_regs;
begin
	$readmemb("regs.mem", cpu_DUT.alu_top_inst.reg_file_inst.mem );	
end
endtask

task init_map_rom;
begin
	$readmemb("map_rom.mem", cpu_DUT.map_prom_inst.mem );	
end
endtask

task run_cycles;
	input integer cycles_no;
begin
	repeat( cycles_no ) begin
		#10
		;
		// nothing
	end
end
endtask

task reset_system;
begin
	#10
		rst = 1;
	#10
		rst = 0;
end

endtask

endmodule
